package prova;

import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;


public class TestQuicksortIncomplete {

	private Quicksort qs;
	private int[][] vectorsToBeOrdered;
	private int numberOfVectors = 4;
	private int sizeOfVectors = 100;
	private int increasingFactor = 10;
	private final int MAX_VALUE = 100000;

	private void generateVectors(){
		vectorsToBeOrdered = new int[numberOfVectors][sizeOfVectors];
		int newSize = sizeOfVectors;
		for (int i = 1; i < numberOfVectors; i++) {
			newSize = newSize*increasingFactor;
			vectorsToBeOrdered[i] = new int[newSize];
		}
		
		//fill all elements with a random number
		for (int i = 0; i < vectorsToBeOrdered.length; i++) {
			for (int j = 0; j < vectorsToBeOrdered[i].length; j++) {
				int randomNumber = (int)(Math.random()*MAX_VALUE);
				vectorsToBeOrdered[i][j] = randomNumber;
			}
		}
	}
	
	@Before
	public void setUp() throws Exception {
		qs = new QuicksortImplIncomplete();
		this.generateVectors();
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testQuicksort() {
		for (int i = 0; i < vectorsToBeOrdered.length; i++) {
			int[] expected = Arrays.copyOfRange(vectorsToBeOrdered[i], 0, vectorsToBeOrdered[i].length);
			Arrays.sort(expected);
			long before = 0;
			long after =0;
			int[] input = Arrays.copyOfRange(vectorsToBeOrdered[i], 0, vectorsToBeOrdered[i].length);
			
			//executando quicksort com insertion e usando embaralhamento
			before = System.nanoTime();
			qs.quicksort(input, 0, vectorsToBeOrdered[i].length - 1, true, true);
			after = System.nanoTime();
			System.out.println("QUICK, EMBARALHAMENTO, INSERTION: " + (after-before) + " nano segundos para entrada de tamanho " + vectorsToBeOrdered[i].length);
			Assert.assertArrayEquals(expected,input);
			
			//executando quicksort com insertion sem embaralhamento
			input = Arrays.copyOfRange(vectorsToBeOrdered[i], 0, vectorsToBeOrdered[i].length);
			before = System.nanoTime();
			qs.quicksort(input, 0, vectorsToBeOrdered[i].length - 1, false, true);
			after = System.nanoTime();
			System.out.println("QUICK, INSERTION: " + (after-before) + " nano segundos para entrada de tamanho " + vectorsToBeOrdered[i].length);
			Assert.assertArrayEquals(expected,input);

			
			//executando quicksort sem insertion e com embaralhamento
			input = Arrays.copyOfRange(vectorsToBeOrdered[i], 0, vectorsToBeOrdered[i].length);
			before = System.nanoTime();
			qs.quicksort(input, 0, vectorsToBeOrdered[i].length - 1, true, false);
			after = System.nanoTime();
			System.out.println("QUICK, EMBARALHAMENTO: " + (after-before) + " nano segundos para entrada de tamanho " + vectorsToBeOrdered[i].length);
			Assert.assertArrayEquals(expected,input);
			
			//executando quicksort sem insertion e sem embaralhamento
			input = Arrays.copyOfRange(vectorsToBeOrdered[i], 0, vectorsToBeOrdered[i].length);
			before = System.nanoTime();
			qs.quicksort(input, 0, vectorsToBeOrdered[i].length - 1, false, false);
			after = System.nanoTime();
			System.out.println("QUICK: " + (after-before) + " nano segundos para entrada de tamanho " + vectorsToBeOrdered[i].length);
			Assert.assertArrayEquals(expected,input);
			
			System.out.println("");
			
		}
	}

}
